package org.example.project.common.middleware.service.redis;

import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.ScanOptions;

import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * @author wenxy
 * @date 2020/10/9
 */
public interface RedisHashService<H, HK, HV> {

    /**
     * Delete given hash {@code hashKeys}.
     *
     * @param key      key
     * @param hashKeys
     * @return
     */
    Long hDelete(H key, Object... hashKeys);

    /**
     * Determine if given hash {@code hashKey} exists.
     *
     * @param key     key
     * @param hashKey hashKey
     * @return
     */
    Boolean hHasKey(H key, Object hashKey);

    /**
     * Get value for given {@code hashKey} from hash at {@code key}.
     *
     * @param key     key
     * @param hashKey hashKey
     * @return
     */
    HV hGet(H key, Object hashKey);

    /**
     * Get values for given {@code hashKeys} from hash at {@code key}.
     *
     * @param key
     * @param hashKeys
     * @return
     */
    List<HV> hMultiGet(H key, Collection<HK> hashKeys);

    /**
     * Increment {@code value} of a hash {@code hashKey} by the given {@code delta}.
     *
     * @param key     key
     * @param hashKey hashKey
     * @param delta   delta
     * @return
     */
    Long hIncrement(H key, HK hashKey, long delta);

    /**
     * Returns the length of the value associated with {@code hashKey}. If either the {@code key} or the {@code hashKey} do not exist, {@code 0} is returned.
     *
     * @param key     key
     * @param hashKey hashKey
     * @return
     */
    Long hLengthOfValue(H key, HK hashKey);

    /**
     * Get size of hash at {@code key}.
     *
     * @param key key
     * @return
     */
    Long hSize(H key);

    /**
     * Set multiple hash fields to multiple values using data provided in {@code m}.
     *
     * @param key key
     * @param m   multiple values
     */
    void hPut(H key, Map<? extends HK, ? extends HV> m);

    /**
     * Set the {@code value} of a hash {@code hashKey}.
     *
     * @param key     key
     * @param hashKey hashKey
     * @param value   value
     */
    void hPut(H key, HK hashKey, HV value);

    /**
     * Set the {@code value} of a hash {@code hashKey} only if {@code hashKey} does not exist.
     *
     * @param key     key
     * @param hashKey hashKey
     * @param value   value
     * @return
     */
    Boolean hPutIfAbsent(H key, HK hashKey, HV value);

    /**
     * Get entire hash stored at {@code key}.
     *
     * @param key key
     * @return
     */
    Map<HK, HV> hGet(H key);

    /**
     * Use a {@link Cursor} to iterate over entries in hash at {@code key}. <br />
     * <strong>Important:</strong> Call {@link Cursor#close()} when done to avoid resource leak.
     *
     * @param key     key
     * @param options options
     * @return
     */
    Cursor<Map.Entry<HK, HV>> hScan(H key, ScanOptions options);

}

